package com.zhichat.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.zhichat.dao.AppVersionDao;
import com.zhichat.dao.SysConfigDao;
import com.zhichat.entity.AppVersionEntity;
import com.zhichat.entity.SysConfigEntity;
import com.zhichat.infrastructure.config.OSSConfig;
import com.zhichat.infrastructure.constants.Constants;
import com.zhichat.infrastructure.exception.http.CommonException;
import com.zhichat.infrastructure.redis.Keys;
import com.zhichat.infrastructure.redis.RedisRepository;
import com.zhichat.infrastructure.redis.rediskey.Key;
import com.zhichat.infrastructure.redis.rediskey.ZhiChat;
import com.zhichat.infrastructure.thread.ThreadPoolWorker;
import com.zhichat.infrastructure.util.OSSClient;
import com.zhichat.infrastructure.util.ThreadLocalCache;
import com.zhichat.model.OSSFileMetaDataModel;
import com.zhichat.service.SysConfigService;
import com.zhichat.web.dto.SysConfigUpdateDTO;
import com.zhichat.web.vo.AppVersionUpdateVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Objects;

@Slf4j
@AllArgsConstructor
@Service
public class SysConfigServiceImpl extends ServiceImpl<SysConfigDao, SysConfigEntity> implements SysConfigService {

    private final RedisRepository redisRepository;
    private final OSSConfig ossConfig;
    private final AppVersionDao appVersionDao;

    @Override
    public SysConfigEntity getSysConfigInfo() {
        Key sysKey = new ZhiChat(Keys.SYS_KEY);
        SysConfigEntity sysConfigEntity = redisRepository.get(sysKey, SysConfigEntity.class);
        if (Objects.nonNull(sysConfigEntity)) {
            return sysConfigEntity;
        }
        // 只有一条信息
        List<SysConfigEntity> sysConfigEntities = baseMapper.selectList(null);
        if (CollectionUtils.isEmpty(sysConfigEntities)) {
            throw new CommonException("系统配置信息不存在");
        }
        ThreadPoolWorker.singleInstance().getExecutor().execute(() -> {
            redisRepository.set(sysKey, sysConfigEntities.get(0));
        });
        return sysConfigEntities.get(0);
    }

    @Override
    public SysConfigEntity updateConfigOfAdmin(SysConfigUpdateDTO dto) {
        MultipartFile robotAvatar = dto.getRobotAvatar();
        MultipartFile robotCoverAvatar = dto.getRobotCoverAvatar();
        if (robotAvatar.isEmpty() || robotCoverAvatar.isEmpty()) {
            throw CommonException.PARAMETER_COMMON_EXCEPTION;
        }
        // 上传头像
        Boolean avatarFlag = OSSClient.uploadFile(robotAvatar, Constants.USER_AVATAR_OSS_FOLDER
                , Objects.requireNonNull(dto.getRobotId()).toString().concat(Constants.IMG_SUF_PNG), ossConfig, null);
        if (!avatarFlag) {
            throw CommonException.FILE_OPERATE_COMMON_EXCEPTION;
        }
        Boolean avatarCoverFlag = OSSClient.uploadFile(robotCoverAvatar, Constants.USER_AVATAR_OSS_FOLDER
                , Objects.requireNonNull(dto.getRobotId()).toString().concat(Constants.IMG_SUF_JPG), ossConfig, null);
        if (!avatarCoverFlag) {
            throw CommonException.FILE_OPERATE_COMMON_EXCEPTION;
        }
        // 修改数据库信息
        LambdaUpdateWrapper<SysConfigEntity> updateWrapper = Wrappers.lambdaUpdate(SysConfigEntity.class);
        updateWrapper.eq(SysConfigEntity::getRobotId, dto.getRobotId());
        SysConfigEntity sysConfigEntity = new SysConfigEntity();
        BeanUtils.copyProperties(dto, sysConfigEntity, "robotId");
        int update = baseMapper.update(sysConfigEntity, updateWrapper);
        if (0 == update) {
            throw CommonException.DB_MODIFY_COMMON_EXCEPTION;
        }
        // 异步 更新缓存
        sysConfigEntity.setRobotId(dto.getRobotId());
        ThreadPoolWorker.singleInstance().getExecutor().execute(() -> {
            Key sysKey = new ZhiChat(Keys.SYS_KEY);
            redisRepository.set(sysKey, JSONObject.toJSONString(sysConfigEntity));
        });
        return sysConfigEntity;
    }

    @Override
    public AppVersionUpdateVO checkUpdate(String appVersion) {
        if (!StringUtils.hasText(appVersion)) {
            return null;
        }
        // 俩种状态 1、全网发布的最新的版本号 2、灰度发布，自己在测试Uid范围内
        AppVersionEntity newVersionEntity = appVersionDao.getNewVersion(appVersion, ThreadLocalCache.getUserId());
        if (Objects.isNull(newVersionEntity)) {
            return null;
        }
        AppVersionUpdateVO resVo = new AppVersionUpdateVO();
        BeanUtils.copyProperties(newVersionEntity, resVo);
        resVo.setVersionDescList(Lists.newArrayList(newVersionEntity.getVersionDesc().split("\\|")));
        OSSFileMetaDataModel fileMetaData = OSSClient.getFileMetaData(Constants.APP_VERSION_FILE_FOLDER, Constants.APP_PREFIX.concat(appVersion).concat(Constants.APP_SUF_EXE), ossConfig);
        if (Objects.isNull(fileMetaData)) {
            throw CommonException.FILE_OPERATE_COMMON_EXCEPTION;
        }
        resVo.setFileName(fileMetaData.getFileName());
        resVo.setFileSize(String.valueOf((fileMetaData.getFileLength() / 1024)).concat(Constants.FILE_SIZE_KB));
        return resVo;
    }

    @Override
    public String downloadApp(String appVersion) {
        // 校验参数
        if (!StringUtils.hasText(appVersion)) {
            throw CommonException.PARAMETER_COMMON_EXCEPTION;
        }
        // 获取文件下载地址
        List<String> fileTmpDownloadUrlList = OSSClient.getFileTmpDownloadUrl(Constants.APP_VERSION_FILE_FOLDER
                , Constants.APP_PREFIX.concat(appVersion).concat(Constants.APP_SUF_EXE)
                , ossConfig);
        if (CollectionUtils.isEmpty(fileTmpDownloadUrlList)) {
            throw CommonException.PARAMETER_COMMON_EXCEPTION;
        }
        // 返回数据
        return fileTmpDownloadUrlList.get(0);
    }
}